package com.example.temp.controller;

import com.example.temp.common.ExcelParseUtil;
import com.example.temp.entity.Question;
import com.example.temp.mapper.QuestionMapper;
import com.example.temp.common.Result;
import com.example.temp.common.RichTextUtil;

import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.net.URLEncoder;
import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@RestController
@RequestMapping("/questionFile")
@Slf4j
public class QuestionFileUploadController {
    private static final Logger logger = LoggerFactory.getLogger(QuestionFileUploadController.class);
    // 使用相对路径，与WebConfig中的配置保持一致
    private static final String IMAGE_DIR = "./images/questions" + File.separator;
    
    // 修复端口号：后端运行在4041端口
    private static final String IMAGE_URL = "http://localhost:4041/questionPictures/";

    @Autowired
    private QuestionMapper questionMapper;
    
    // 在类初始化时确保图片目录存在
    static {
        try {
            File imageDir = new File("./images/questions");
            if (!imageDir.exists()) {
                boolean created = imageDir.mkdirs();
                if (created) {
                    LoggerFactory.getLogger(QuestionFileUploadController.class)
                        .info("创建图片目录: {}", imageDir.getAbsolutePath());
                } else {
                    LoggerFactory.getLogger(QuestionFileUploadController.class)
                        .warn("无法创建图片目录: {}", imageDir.getAbsolutePath());
                }
            } else {
                LoggerFactory.getLogger(QuestionFileUploadController.class)
                    .info("图片目录已存在: {}", imageDir.getAbsolutePath());
            }
        } catch (Exception e) {
            LoggerFactory.getLogger(QuestionFileUploadController.class)
                .error("初始化图片目录失败", e);
        }
    }

    @PostMapping("/upload")
    public Result uploadQuestionFile(
            @RequestParam("categoryId") Integer categoryId,
            @RequestParam("file") MultipartFile file,
            @RequestParam(value = "teacherId", required = false) String teacherId) {
        if (file.isEmpty()) {
            return Result.fail("上传文件不能为空");
        }

        try (InputStream inputStream = file.getInputStream()) {
        
                List<String> errorList = new ArrayList<>();
                List<Question> questions = parseExcelFile(inputStream,errorList);
         
                if (!errorList.isEmpty()) {
                    return Result.fail("部分/全部数据格式有误",
                            Collections.singletonMap("errors", errorList));
                }

            if (questions.isEmpty()) {
                logger.warn("Excel文件中没有找到有效的题目数据");
                return Result.fail("Excel文件中没有找到有效的题目数据，请检查文件格式是否正确");
            }
            
            // 为所有题目设置teacherId和categoryId
            if (teacherId != null && !teacherId.isEmpty()) {
                for (Question question : questions) {
                    question.setTeacherId(teacherId);
                    question.setCategoryId(categoryId);
                }
            }
            
            logger.info("准备批量插入 {} 条题目数据", questions.size());
            int result = questionMapper.batchInsert(questions);
            logger.info("成功导入 {} 条题目数据", result);
            return Result.success(result);
 
 
 
        } catch (IOException e) {
            logger.error("文件读取失败：", e);
            return Result.fail("文件处理失败");
        } catch (Exception e) {
            logger.error("题目导入异常：", e);
            return Result.fail("系统处理异常");
        }
 
    }

    /**
     * 读取Excel文件并解析其中的题目数据
     * 
     * @param inputStream Excel文件输入流
     * @return 一个包含解析结果的题目列表
     * @throws IOException 文件读取失败时抛出
     */
    private List<Question> parseExcelFile(InputStream inputStream,
    List<String> errorList) throws IOException {
        List<Question> questions = new ArrayList<>();
    
        try (Workbook workbook = WorkbookFactory.create(inputStream)) {
            Sheet sheet = workbook.getSheetAt(0);

            // 读取Excel文件时，跳过第一行（表头行）
            for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
                Row row = sheet.getRow(rowIndex);
                if (ExcelParseUtil.isRowEmpty(row)) continue;

                try {
                    // 解析当前行的题目数据
                    Question question = parseQuestionRow(row, workbook, rowIndex);
                    if (isValidQuestion(question)) {
                        questions.add(question);
                    }
                } catch (ParseException e) {
                    errorList.add("第" + (rowIndex + 1) + "行：" + e.getMessage());
                    logger.warn(" 跳过第 {} 行：{}", rowIndex + 1, e.getMessage());
                }
            }
        }

      
        return questions;
    }

    private Question parseQuestionRow(Row row, Workbook workbook, int rowIndex) throws ParseException {
        Question question = new Question();

        // 智能检测Excel格式：判断是否包含ID列
        // 如果第一列是数字且第二列是文本，则可能包含ID列
        boolean hasIdColumn = true;
        int columnOffset = hasIdColumn ? 1 : 0; // 如果有ID列，所有列索引偏移+1
        
        logger.debug("第{}行格式检测: hasIdColumn={}, columnOffset={}", rowIndex + 1, hasIdColumn, columnOffset);
        //

        // 解析类型
        String type = ExcelParseUtil.getCellStringValue(row.getCell(columnOffset));
        if (type == null || type.isEmpty()) {
            throw new ParseException("题目类型不能为空");
        }
        question.setType(type);

          // 解析问题文本
          String questionText = ExcelParseUtil.getCellStringValue(row.getCell(columnOffset + 1));
          if (questionText == null || questionText.isEmpty()) {
              throw new ParseException("问题文本不能为空");
          }

        // 解析图片URL（可选）
        String imageUrl = handleImage(row, workbook, rowIndex);
       
       // 将文本和图片URL转换为富文本格式
        String richText = RichTextUtil.convertToRichText(questionText, imageUrl);
        question.setQuestionText(richText);

          
        // 解析答案
        String answer = ExcelParseUtil.getCellStringValue(row.getCell(columnOffset + 3));
        if (answer == null || answer.isEmpty()) {
            throw new ParseException("答案不能为空");
        }
        String richTextAnswer = RichTextUtil.convertToRichText(answer, null);
        question.setAnswer(richTextAnswer);

        // 解析答题时间
        Integer answerTime = ExcelParseUtil.getCellIntegerValue(row.getCell(columnOffset + 4));
        if (answerTime == null || answerTime <= 0) {
            throw new ParseException("无效的答题时间");
        }
        question.setAnswerTime(answerTime);
         
        //解析默认得分
        Integer score = ExcelParseUtil.getCellIntegerValue(row.getCell(columnOffset + 5));
        if (score == null || score <= 0) {
            throw new ParseException("无效的默认得分");
        }
        question.setScore(score);   
      
        return question;
    }
   

    // 保存图片返回图片URL
    private String handleImage(Row row, Workbook workbook, int rowIndex) {
        // 固定图片 URL 列为第 4 列（索引 3）
        int imageUrlColumnIndex = 3;
        
        logger.debug("处理第{}行图片，imageUrlColumnIndex={}", rowIndex + 1, imageUrlColumnIndex);
        
        Drawing<?> drawing = row.getSheet().getDrawingPatriarch();
        if (drawing != null) {
            logger.debug("第{}行找到绘图对象", rowIndex + 1);
            for (Object obj : drawing) {
                if (obj instanceof Picture) {
                    Picture picture = (Picture) obj;
                    logger.debug("找到图片对象，检查是否属于第{}行", rowIndex + 1);
                    if (isPictureInRow(picture, rowIndex)) {
                        logger.info("第{}行包含图片，开始处理", rowIndex + 1);
                        PictureData pictureData = picture.getPictureData();
                        if (pictureData != null) {
                            String extension = getFileExtension(pictureData.getMimeType());
                            logger.debug("图片MIME类型: {}, 扩展名: {}", pictureData.getMimeType(), extension);
                            if (extension != null) {
                                String fileName = UUID.randomUUID().toString() + "." + extension;
                                String filePath = IMAGE_DIR + fileName;
                                logger.info("保存图片到: {}", filePath);
                                try (FileOutputStream outputStream = new FileOutputStream(filePath)) {
                                    outputStream.write(pictureData.getData());
                                    String imageUrl = IMAGE_URL + fileName;
                                    logger.info("图片保存成功，URL: {}", imageUrl);
                                    // 返回图片的 URL 地址
                                    return imageUrl;
                                } catch (IOException e) {
                                    logger.error("保存图片失败（第 {} 行）：", rowIndex + 1, e);
                                }
                            } else {
                                logger.warn("第{}行图片格式不支持: {}", rowIndex + 1, pictureData.getMimeType());
                            }
                        } else {
                            logger.warn("第{}行图片数据为空", rowIndex + 1);
                        }
                    }
                }
            }
        } else {
            logger.debug("第{}行没有绘图对象", rowIndex + 1);
        }

        // 如果没有图片，尝试从单元格中读取图片URL
        String cellImageUrl = ExcelParseUtil.getCellStringValue(row.getCell(imageUrlColumnIndex));
        logger.debug("第{}行从单元格读取图片URL: {}", rowIndex + 1, cellImageUrl);
        return cellImageUrl;
    }

    // 检查图片是否属于当前行
    private boolean isPictureInRow(Picture picture, int rowIndex) {
        // 使用 ClientAnchor 来获取图片的位置
        ClientAnchor anchor = (ClientAnchor) picture.getAnchor();
        return anchor.getRow1() == rowIndex; // 判断图片是否位于当前行
    }

    private String getFileExtension(String mimeType) {
        if ("image/jpeg".equals(mimeType)) {
            return "jpg";
        } else if ("image/png".equals(mimeType)) {
            return "png";
        }
        return null;
    }

    private boolean isValidQuestion(Question question) {
        return !question.getType().isEmpty()
                && !question.getQuestionText().isEmpty()
                && !question.getAnswer().isEmpty()
                && question.getAnswerTime() > 0;
    }

    // 自定义解析异常
    private static class ParseException extends Exception {
        public ParseException(String message) {
            super(message);
        }
    }

    @GetMapping("/template/download")
    public ResponseEntity<Resource> downloadTemplate() {
        try {
          String projectRoot = System.getProperty("user.dir"); // 获取项目根目录
          String templatePath = projectRoot + "/images/questions/题库模板.xlsx";
          File templateFile = new File(templatePath);
            
            if (!templateFile.exists()) {
                logger.warn("模板文件不存在: {}", templateFile.getAbsolutePath());
                return ResponseEntity.notFound().build();
            }
            
            
            Resource resource = new FileSystemResource(templateFile);
            logger.info("下载模板文件: {}", templateFile.getAbsolutePath());
            
            // 对文件名进行URL编码
            String encodedFilename = URLEncoder.encode("题库模板.xlsx", "UTF-8").replaceAll("\\+", "%20");
            String contentDisposition = String.format("attachment; filename*=UTF-8''%s", encodedFilename);
            
            return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION, contentDisposition)
                    .header(HttpHeaders.CONTENT_TYPE, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
                    .header(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, must-revalidate")
                    .header(HttpHeaders.PRAGMA, "no-cache")
                    .header(HttpHeaders.EXPIRES, "0")
                    .body(resource);
                    
        } catch (Exception e) {
            logger.error("下载模板文件失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
}
